##
# The Exam Controller handles the creation and modification of exams
class ExamController < ApplicationController
	helper :paginator
	helper :right
	include PaginatorHelper
	include RightHelper
  layout  'scaffold'

  ##
  # the this method redirects to the list-method
  def index
    list
    render :action => 'list'
  end

  # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
  verify :method => :post, :only => [ :destroy, :create, :update ],
         :redirect_to => { :action => :list }
	# Session must be active
	verify :session => 'user',
				 :redirect_to => { :controller => 'user', :action => :login },
				 :add_flash => { :error => 'you must be logged in to create exams' }

  # verify that only teachers can access this controller
	before_filter :verify_teacher
  # verify that only the owner of an exam can see, edit and destroy it
	before_filter :verify_owner, :only => [:show, :edit, :destroy, :update]
  # verify that a teacher cannot edit or update already taken exams
  before_filter :verify_user_answers, :only => [ :edit, :update ]

  ## 
  # lists all available exams for the logged in teacher
  def list
    @users = User.find(:all, :conditions => [ '(rights & 2) > 0 ' \
                                               ' and id != ?', 
                                               session['user'].id ])
    @exam_pages, @exams = 
			paginate_collection Exam.find(:all, :conditions => 
																		["user_id = ?", session["user"].id]), 
                                    :order => 'id desc',
													:per_page => 10, :page => params[:page]
  end

  ##
  # displays one exam
  def show
    @exam = Exam.find(params[:id])
  end

  ##
  # displays an empty creation form for an exam
  def new
    @exam = Exam.new
  end

  ##
  # stores a new exam into the database. The information for this comes from 
  # the corresponding POST-variables
  def create
#   evaluate questions...
		exam = Exam.new
		exam.user = session['user']
		exam.title = params[:exam][:title]
    exam.percent_1 = params[:exam][:percent_1]
    exam.percent_2 = params[:exam][:percent_2]
    exam.percent_3 = params[:exam][:percent_3]
    exam.percent_4 = params[:exam][:percent_4]
		exam.save

		eval_form(exam)

		flash[:notice] = 'Exam was successfully created.'
		redirect_to :action => 'list'
  end

  ## 
  # Creates the questions and answers for a submitted form from their 
  # POST-Variables
  # @param exam is a exam-instance which belongs to the answers and questions
  #        in the POST-variables
	def eval_form(exam)
		i = 0
		if(params[:question].nil?) 
			return
		end
		params[:question][:text].each do |t|
			q = Question.new
			q.text = t
			q.score = params[:question][:score][i]
			q.exam = exam
			q.checkbox = 0
			q.checkbox = 1 if params[:question][:type][i] == "radiobutton" 

			id = params[:question][:id][i]
			if(!params['question_' + id.to_s].nil?)
				j = 0
				params['question_' + id.to_s][:answer].each do |t|
					a = Answer.new
					a.text = t
					a.correctness = 0
					a.correctness = 1 if params['question_' + id.to_s][:correct][j] == 'correct'
					q.answers << a
					j = j + 1
				end
			end
			q.save
			
			i = i + 1
		end
	end

  ##
  # Creates an edit-form for an exam
  def edit
    @exam = Exam.find(params[:id])
  end

  ##
  # updates an exam from POST-variables
  def update
    @exam = Exam.find(params[:id])
    @exam.update_attributes(params[:exam])

		# this is probably not the best solution...
		@exam.questions.each do |q|
			q.answers.each { |a| a.destroy }
			q.destroy
		end
		# fill the question-fields...
		eval_form(@exam)
	
		flash[:notice] = 'Exam was successfully updated.'
		redirect_to :action => 'show', :id => @exam
  end

  ##
  # destroys the exam, whose ID is in the GET-variable
  def destroy
    exam = Exam.find(params[:id])
		exam.questions.each do |q|
			q.answers.each { |a| a.user_answers.each { |ua| ua.destroy }; a.destroy }
			q.destroy
		end
    exam.exam_results.each { |r| r.destroy }
		exam.destroy
    redirect_to :action => 'list'
  end
  
  ##
  # copies the exam, whose ID is in the GET-variables
  def copy
    exam = Exam.find(params[:id])
    new_exam = exam.deep_copy
    new_exam.save
    redirect_to :action => 'list'
  end
  
  ##
  # Change the owner of an exam. The parameters for this method are in the
  # GET-variables
  def change
    redirect_to :action => 'list' if params[:user_id].nil?
    redirect_to :action => 'list' if params[:id].nil?
    
    user = User.find(params[:user_id])
    exam = Exam.find(params[:id])
    exam.user = user
    exam.save
    
    flash[:notice] = "Owner was successfully changed"
    redirect_to :action => 'list'
  end

	private
  
  ##
  # Verifies that the exam-id in the GET-variable belongs to the teacher, that
  # is currently logged in.
	def verify_owner
		id = params[:id]
		begin
			exam = Exam.find(id)
		rescue => err
      flash[:error] = "Exam doesn't exists";
			redirect_to :action => 'list'
			return
		end

		if(exam.user != session['user'])
			flash[:error] = 'You are not the owner of this exam.'
			redirect_to :action => 'list'
		end
	end
  
  ##
  # Verifies that no user has answered the corresponding exam in the 
  # GET-variable yes.
  def verify_user_answers
    exam = Exam.find(params[:id])
    exam.questions.each do |q|
      q.answers.each do |a|
        a.user_answers.each do |ua| 
          flash[:error] = "Sorry, but there are already answered questions " \
                          "in this exam"
          redirect_to :action => 'list'
          return
        end
      end
    end
  end
end
